package com.cby.code.net.task;

import com.cby.code.net.Request;
import com.cby.code.net.Response;
import com.cby.code.net.policy.RetryPolicy;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.Map;

/**
 * @description: HttpUrlUploadFileTask
 * @author: ChenBaoYang
 * @createDate: 2022/3/8 4:55 下午
 */
public class HttpUrlUploadFileTask extends BaseTask{

    @Override
    public Response performRequest(Request request) {
        HttpURLConnection connection = null;
        try {
            // 创建连接
            connection = createConnection(request);
            // 设置请求头
            setHeaders(connection, request.getParam());
            // 设置请求参数和请求方式
            //setConnectionParametersForRequest(connection, request);
            //设置上传文件
            connection.setRequestMethod("POST");
            setUploadFileData(connection, request);
            // 解析相应数据
            return parseResponse(connection);
        } catch (Exception e) {
            RetryPolicy policy = request.getRetryPolicy();
            if (policy != null) {
                policy.retry(e);
            }
        } finally {
            closeConnection(connection);
        }
        return null;
    }

    private void setUploadFileData(HttpURLConnection connection, Request request) throws IOException {
        //设置文件类型
        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + "*****");
        File file = new File(request.getFilePath());
        String name = file.getName();
        DataOutputStream requestStream = new DataOutputStream(connection.getOutputStream());
        requestStream.writeBytes("--" + "*****" + "\r\n");
        //发送文件参数信息
        StringBuilder tempParams = new StringBuilder();
        tempParams.append("Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + name + "\"; ");
        int pos = 0;
        Map<String, Object> paramsMap = request.getParam().getParam();
        int size = paramsMap.size();
        for (String key : paramsMap.keySet()) {
            tempParams.append( String.format("%s=\"%s\"", key, paramsMap.get(key), "utf-8"));
            if (pos < size-1) {
                tempParams.append("; ");
            }
            pos++;
        }
        tempParams.append("\r\n");
        tempParams.append("Content-Type: application/octet-stream\r\n");
        tempParams.append("\r\n");
        String params = tempParams.toString();
        requestStream.writeBytes(params);
        //发送文件数据
        FileInputStream fileInput = new FileInputStream(file);
        int bytesRead;
        byte[] buffer = new byte[1024];
        DataInputStream in = new DataInputStream(new FileInputStream(file));
        while ((bytesRead = in.read(buffer)) != -1) {
            requestStream.write(buffer, 0, bytesRead);
        }
        requestStream.writeBytes("\r\n");
        requestStream.flush();
        requestStream.writeBytes("--" + "*****" + "--" + "\r\n");
        requestStream.flush();
        fileInput.close();
    }

    /**
     * 解析响应数据信息
     * @param urlConnection
     */
    protected Response parseResponse(HttpURLConnection urlConnection) throws Exception {
        int httpStatus = urlConnection.getResponseCode();
        if (isOK(httpStatus)) {
            String result = streamToString(urlConnection.getInputStream());

            return new Response(result, httpStatus,"");
        } else {
            return new Response(null, httpStatus, urlConnection.getResponseMessage());
        }
    }
}
